/*
 * ----------------------------------------------------------------------------
 * "THE BEER-WARE LICENSE" (Revision 42):
 * <rom.prevot@gmail.com> wrote this file. As long as you retain this notice you
 * can do whatever you want with this stuff. If we meet some day, and you think
 * this stuff is worth it, you can buy me a beer in return R. Prevot
 * ----------------------------------------------------------------------------
 */

/******************************************************************************\
 *          ____                _______    _____ _             _              *
 *         |  _ \              |__   __|  / ____| |           | |             *
 *         | |_) | ___  _ __ _ __ | | ___| (___ | |_ ___   ___| | __          *
 *         |  _ < / _ \| '__| '_ \| |/ _ \\___ \| __/ _ \ / __| |/ /          *
 *         | |_) | (_) | |  | | | | | (_) |___) | || (_) | (__|   <           *
 *         |____/ \___/|_|  |_| |_|_|\___/_____/ \__\___/ \___|_|\_\          *
 *                                                                            *
\******************************************************************************/

package app.models;

import app.App;
import app.exceptions.ReferenceOutOfStockException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

/**
 *
 * @author Ghost
 */
@Entity
@Table(name = "ventes", catalog = "BornToStock", schema = "")
@NamedQueries({
    @NamedQuery(name = "Vente.findAll", query = "SELECT v FROM Vente v"),
    @NamedQuery(name = "Vente.findById", query = "SELECT v FROM Vente v WHERE v.id = :id"),
    @NamedQuery(name = "Vente.findByDateV", query = "SELECT v FROM Vente v WHERE v.dateV = :dateV"),
    @NamedQuery(name = "Vente.findByType", query = "SELECT v FROM Vente v WHERE v.type = :type"),
    @NamedQuery(name = "Vente.findByBeauTemps", query = "SELECT v FROM Vente v WHERE v.beauTemps = :beauTemps")})
public class Vente implements Serializable {
    
    //Type enum...
    public final static String TYPE_CB        = "cb";
    public final static String TYPE_CHEQUE    = "cheque";
    public final static String TYPE_ESPECES   = "espece";
    
    private static final long serialVersionUID = 1L;
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id", nullable = false)
    private Integer id;
   
    @Basic(optional = false)
    @Column(name = "dateV", nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date dateV;
    
    @Column(name = "type", length = 6)
    private String type;
    
    @Basic(optional = false)
    @Column(name = "beauTemps", nullable = false)
    private boolean beauTemps;
    
    @JoinColumn(name = "client_id", referencedColumnName = "id")
    @ManyToOne(fetch = FetchType.EAGER)
    private Client client;
    
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "vente", fetch = FetchType.EAGER)
    private List<Lignevente> ligneventeList = new ArrayList<Lignevente>();

    public Vente() {
    }

    public Vente(Integer id) {
        this.id = id;
    }

    public Vente(Integer id, Date dateV, boolean beauTemps) {
        this.id = id;
        this.dateV = dateV;
        this.beauTemps = beauTemps;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Date getDateV() {
        return dateV;
    }

    public void setDateV(Date dateV) {
        this.dateV = dateV;
    }

    public String getType() {
        if(type == null){
            type = "";
        }
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public boolean getBeauTemps() {
        return beauTemps;
    }

    public void setBeauTemps(boolean beauTemps) {
        this.beauTemps = beauTemps;
    }

    public Client getClient() {
        return client;
    }

    public void setClient(Client client) {
        this.client = client;
    }

    public List<Lignevente> getLigneventeList() {
        return ligneventeList;
    }

    public void setLigneventeList(List<Lignevente> ligneventeList) {
        this.ligneventeList = ligneventeList;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Vente)) {
            return false;
        }
        Vente other = (Vente) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        String str = "Vente{" + "id=" + id + ", dateV=" + dateV + ", "
                + "type=" + type + ", beauTemps=" + beauTemps + ", "
                + "client=" + client + ", ligneventeList=[";
        for(Lignevente lv : ligneventeList){
            str += lv;
        }
        str += "]}";
        return str;
    }

    
    
    public void cancel(){
        for(Lignevente lv : ligneventeList){ 
            lv.cancel();
        }
        //nettoyage de la liste des ventes
        ligneventeList.clear();
        client = null;
    }
    
    /**
     * Ajout une ligne et retire la quantité du stock
     * @param lv 
     */
    public void ajouterLigneVente(Lignevente lv) {
        Reference ref = lv.getReference();
        try{
            App.getInstance().getCatalogue().pickReference(ref, lv.getQuantite());
            //si on a déjà une ligne avec la même ref et au même prix:
            for(Lignevente ligne : ligneventeList){
                if(ligne.getReference().equals(lv.getReference()) && 
                        ligne.getPxVente() == lv.getPxVente()){
                    //on fusionne les 2
                    ligne.setQuantite(ligne.getQuantite() + lv.getQuantite());
                    return;
                }
            }
            //sinon on continue normalement.
            lv.setVente(this);
            lv.getReference().getLigneventeList().add(lv);
            this.ligneventeList.add(lv);
        } catch (ReferenceOutOfStockException refEx){
            App.displayMessage(refEx.getRef() + " n'est pas disponible (pas assez?)", App.MESSAGE_TYPE.ERROR);
        }
    }
    
    /**
     * Le total de la vente
     * @return 
     */
    public float getTotal(){
        float tot = 0.f;
        for(Lignevente lv : ligneventeList){
            tot += lv.getTotal();
        }
        
        return tot;
    }

    
}
